#include <LiquidCrystal_I2C.h>  // 导入LCD1602 I2C驱动库
#include <Wire.h>               // 导入I2C通信库（LCD1602 I2C模式依赖）
#include <Keypad.h>             // 导入矩阵键盘库

// -------------------------- 硬件参数配置 --------------------------
const uint8_t LCD_ADDR = 0x27;  // LCD1602的I2C设备地址（常见0x27或0x3F）
const uint8_t LCD_COLS = 16;    // LCD1602列数（16列）
const uint8_t LCD_ROWS = 2;     // LCD1602行数（2行）

// 矩阵键盘配置（4行4列）
const byte KEYPAD_ROWS = 4;  // 键盘行数
const byte KEYPAD_COLS = 4;  // 键盘列数

// 键盘按键映射表（与实际按键位置对应）
char keyMap[KEYPAD_ROWS][KEYPAD_COLS] = {
  { '1', '2', '3', 'A' },
  { '4', '5', '6', 'B' },
  { '7', '8', '9', 'C' },
  { '*', '0', '#', 'D' }
};

// 键盘行引脚（连接Arduino数字引脚）
byte rowPins[KEYPAD_ROWS] = { 11, 10, 9, 8 };
// 键盘列引脚（连接Arduino数字引脚）
byte colPins[KEYPAD_COLS] = { 7, 6, 5, 4 };

// -------------------------- 全局对象与变量 --------------------------
LiquidCrystal_I2C lcd(LCD_ADDR, LCD_COLS, LCD_ROWS);  // LCD1602对象实例化
Keypad customKeypad = Keypad(                         // 矩阵键盘对象实例化
  makeKeymap(keyMap),                                 // 按键映射表
  rowPins,                                            // 行引脚数组
  colPins,                                            // 列引脚数组
  KEYPAD_ROWS,                                        // 行数
  KEYPAD_COLS                                         // 列数
);

uint8_t inputCount = 0;  // 记录按键输入次数（用于控制LCD显示位置）

// -------------------------- 初始化函数 --------------------------
void setup() {
  lcd.init();               // 初始化LCD1602
  lcd.backlight();          // 开启LCD背光
  lcd.setCursor(0, 0);      // 设置初始光标位置（第0列，第0行）
  lcd.print("loading...");  // 开机欢迎提示
  delay(1500);              // 提示显示1.5秒
  lcd.clear();              // 清屏准备接收输入
}

// -------------------------- 主循环函数 --------------------------
void loop() {
  char pressedKey = customKeypad.getKey();  // 获取按键输入（无按键时返回0）

  // 检测到有效按键输入
  if (pressedKey != 0) {
    // 根据输入次数计算光标位置
    // 第0行：输入次数0-15（对应列0-15）
    // 第1行：输入次数16-31（对应列0-15）
    uint8_t col = inputCount % LCD_COLS;  // 计算列位置（取余16）
    uint8_t row = inputCount / LCD_COLS;  // 计算行位置（整除16）

    lcd.setCursor(col, row);  // 设置光标到当前输入位置
    lcd.print(pressedKey);    // 在当前位置显示按键字符

    inputCount++;  // 输入次数自增

    // 当输入满32个字符（2行×16列），清屏重置
    if (inputCount >= LCD_COLS * LCD_ROWS) {
      delay(500);      // 延迟500ms，让最后一个字符显示完整
      lcd.clear();     // 清屏
      inputCount = 0;  // 重置输入计数
    }
  }
}